package com.bckj.fastboot.core.extra.easyexcel;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author wfc
 */
public class EasyExcelUtils {

    /**
     * 导出excel
     * @param response 输出流
     * @param data 数据
     * @param clazz class
     * @param <T> 泛型
     */
    public static <T> void exportExcel(HttpServletResponse response, List<T> data, Class<T> clazz) {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");

        try {
            String fileName =  System.currentTimeMillis() + ExcelTypeEnum.XLSX.getValue();
            fileName = URLEncoder.encode(fileName, String.valueOf(StandardCharsets.UTF_8));
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

            OutputStream outputStream = response.getOutputStream();
            EasyExcel.write(outputStream, clazz).sheet(0)
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .doWrite(data);

        } catch (IOException e) {
            throw new RuntimeException("导出Excel失败", e);
        }
    }

    /**
     * 导出多sheet excel
     * @param response 输出流
     * @param sheetsData map
     */
    public static void exportExcel(HttpServletResponse response, Map<String, List<?>> sheetsData) {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");

        try {
            String fileName =  System.currentTimeMillis() + ExcelTypeEnum.XLSX.getValue();
            fileName = URLEncoder.encode(fileName, String.valueOf(StandardCharsets.UTF_8));
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

            OutputStream outputStream = response.getOutputStream();
            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
            int sheetIndex = 0;

            for (Map.Entry<String, List<?>> entry : sheetsData.entrySet()) {
                if (!entry.getValue().isEmpty()) {
                    Class<?> clazz = entry.getValue().get(0).getClass();
                    WriteSheet writeSheet = EasyExcel.writerSheet(sheetIndex, entry.getKey()).head(clazz).build();
                    excelWriter.write(entry.getValue(), writeSheet);
                    sheetIndex++;
                }
            }

            excelWriter.finish();
        } catch (IOException e) {
            throw new RuntimeException("导出Excel失败", e);
        }
    }

    /**
     * 导入数据
     * @param file 文件
     * @param clazz class
     * @return 数据列表
     * @param <T> 泛型
     * @throws IOException 异常
     */
    public static <T> List<T> importExcel(MultipartFile file, Class<T> clazz) throws IOException {
        InputStream inputStream = file.getInputStream();
        return EasyExcel.read(inputStream, clazz, null).sheet().doReadSync();
    }


    /**
     * 获得文件后缀
     *
     * @param extension 文件后缀名
     * @return ExcelType
     */
    public static ExcelTypeEnum getEnumByExtension(String extension) {
        String fileExtension = extension.startsWith(".") ? extension : "." + extension;
        return Arrays.stream(ExcelTypeEnum.values())
                .filter(e -> e.getValue().equalsIgnoreCase(fileExtension))
                .findFirst()
                .orElseThrow(() -> new RuntimeException(String.format("类型不存在,extension:[%s]", fileExtension)));
    }
}
